// <copyright file="AccountsController.cs" company="Clever Software">
// Copyright (c) 2013, 2014 All Right Reserved, http://www.cleversoftware.by
//
// This source is subject to the Microsoft Permissive License.
// Please see the License.txt file for more information.
// All other rights reserved.
//
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// </copyright>
// <author>Clever Software</author>
// <email>info@cleversoftware.by</email>
// <date>2014-02-04</date> 
// <summary>CleverCMS source code</summary>

namespace CleverCMS.Web.Cms.Admin.Controllers
{
    using System;
    using System.Linq;
    using System.Collections.Generic;
    using System.Web.Mvc;
    using System.Web.Security;
    using WebMatrix.WebData;

    using Common.Logging;
    using CleverCMS.Core.Services;
    using CleverCMS.Cms.Data.Entities;
    using CleverCMS.Cms.Services;
    using CleverCMS.Cms.Services.ViewModels;

    [Authorize(Roles = "Admin")]
    public class AccountsController : Controller
    {
        private readonly AccountService m_userService;
        private readonly LoggingService m_loggingService;

        public AccountsController(AccountService userService,
                                  LoggingService loggingService)
        {
            m_userService = userService;
            m_loggingService = loggingService;
        }

        public ViewResult List()
        {
            return View();
        }

        [HttpPost]
        public JsonResult ListUsers(int jtStartIndex = 0, int jtPageSize = 0, string jtSorting = null)
        {
            try
            {
                int count = 0;
                IEnumerable<UserProfile> allPages = m_userService.LoadAllUsers(jtStartIndex, jtPageSize, jtSorting, out count).ToList();
                return Json(new { Result = "OK", Records = allPages, TotalRecordCount = count });
            }
            catch (Exception ex)
            {
                return Json(new { Result = "ERROR", Message = ex.Message });
            }
        }

        public ViewResult Edit(int? id)
        {
            if (id != null && id != 0)
            {
                UserProfile user = m_userService.LoadUser(id.Value);
                Role role = m_userService.GetRoleByName(Roles.GetRolesForUser(user.Name).FirstOrDefault());
                List<Role> roles = m_userService.LoadAllRoles().ToList();

                return View(new AdminEditUserViewModel
                {
                    Id = user.Id,
                    CreatedAt = user.CreatedAt,
                    DisplayName = user.DisplayName,
                    Email = user.Email,
                    Login = user.Login,
                    Password = user.Password,
                    RoleId = role != null ? role.RoleId : 0,
                    Roles = roles
                });
            }
            return View(new AdminEditUserViewModel() { Roles = m_userService.LoadAllRoles().ToList() });
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(AdminEditUserViewModel user)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    if (user.Id != 0)
                    {
                        if (!String.IsNullOrEmpty(user.Password) && !String.IsNullOrEmpty(user.CurrentPassword))
                            if (!WebSecurity.ChangePassword(user.Login, user.CurrentPassword, user.Password))
                                return Json(new { success = false, error = "Password does not changed" });

                        var userProfile = new UserProfile
                        {
                            Id = user.Id,
                            Login = user.Login,
                            DisplayName = user.DisplayName,
                            Email = user.Email,
                            CreatedAt = user.CreatedAt,
                            Password = user.Password
                        };
                        m_userService.UpdateUser(userProfile);

                        foreach (var roleName in Roles.GetRolesForUser(user.Login))
                        {
                            Roles.RemoveUserFromRole(user.Login, roleName);    
                        }

                        var role = m_userService.LoadAllRoles().FirstOrDefault(x => x.RoleId == user.RoleId);
                        if (role != null)
                            Roles.AddUserToRole(user.Login, role.RoleName);

                        m_loggingService.Info("User '" + user.Login + "' is changes.");
                        return Json(new { success = true, error = "", id = user.Id });
                    }
                    else
                    {
                        WebSecurity.CreateUserAndAccount(user.Login, user.Password,
                               new
                               {
                                   DisplayName = user.DisplayName,
                                   CreatedAt = DateTime.Now,
                                   Email = user.Email
                               });

                        var role = m_userService.LoadAllRoles().FirstOrDefault(x => x.RoleId == user.RoleId);
                        if (role != null)
                            Roles.AddUserToRole( user.Login, role.RoleName);

                        m_loggingService.Info("User '" + user.Login + "' is created.");
                        return Json(new { success = true, error = "", id = WebSecurity.GetUserId(user.Login) });
                    }
                }
                catch (Exception exc)
                {
                    var v = new { Result = "ERROR", Message = exc.Message, success = false, error = exc.Message };
                    return Json(v);
                }
            }
            else
            {
                string errorMessage = "";
                var errorsList = ModelState.Values.SelectMany(x => x.Errors);
                foreach (var modelError in errorsList)
                {
                    errorMessage += modelError.ErrorMessage + "<br />";
                }
                var v = new { success = false, error = errorMessage };
                return Json(v);
            }
        }

        [HttpPost]
        [Authorize]
        public ActionResult Delete(int? Id)
        {
            if (!ModelState.IsValid)
            {
                var v = new {Result = "ERROR", Message = "", success = false, error = "Unknown error" };
                return Json(v);
            }

            try
            {
                if (Id != null)
                {
                    var membership = (SimpleMembershipProvider)System.Web.Security.Membership.Provider;
                    var user = membership.GetUserNameFromId(Id.Value);

                    membership.DeleteAccount(membership.GetUserNameFromId(Id.Value));
                    membership.DeleteUser(membership.GetUserNameFromId(Id.Value), false);

                    m_loggingService.Warn("User '" + user + "' is deleted.");
                    var v = new {Result = "OK", Message = "", success = true, error = "", userId = Id };
                    return Json(v);
                }
                else
                {
                    var v = new {Result = "ERROR", Message = "", success = false, error = "Unknown error" };
                    return Json(v);
                }
            }
            catch (Exception exc)
            {
                var v = new {Result = "ERROR", Message = exc.Message, success = false, error = exc.Message };
                return Json(v);
            }
        }

    }
}